/*
 * Copyright (c) 2010-2011 Josef Hardi <josef.hardi@gmail.com>
 * Copyright (c) 2010 Piotr Zagawa <piotr.zagawa@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package id.duapuluhdua.dakidaki.loader;

import java.util.ArrayList;

import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.Log;

import id.duapuluhdua.dakidaki.MainState;
import id.duapuluhdua.dakidaki.R;
import id.duapuluhdua.dakidaki.activities.ActivityMain;
import id.duapuluhdua.dakidaki.gps.GpsLocationStatus;
import id.duapuluhdua.dakidaki.layers.LayerLocation;
import id.duapuluhdua.dakidaki.map.Screen;
import id.duapuluhdua.dakidaki.map.Viewport;

/**
 * A data loader is responsible to place several information regarding the
 * track route, various sites (e.g., peaks, towns, bus stops) to the
 * screen.
 */
public class DataLoader
{
  /** Fields */
  private ActivityMain mParent;
  private MainState mState;
  private Screen mScreen;
  private GpsLocationStatus mGpsLocationStatus;

  // Data
  private TrackLoader mTrackLoader;

  private boolean bSelectOpenTrackAtStart = true;
  private String mMsgLocationTrackingOff;

  public DataStats mStats;

  /**
   * The constructor.
   *
   * @param parent
   */
  public DataLoader(ActivityMain parent)
  {
    mParent = parent;
    mState = parent.getMainState();
    mScreen = new Screen();
    mGpsLocationStatus = new GpsLocationStatus();

    mTrackLoader = new TrackLoader(parent, mScreen, mGpsLocationStatus);
    mStats = new DataStats(parent, mGpsLocationStatus);

    mMsgLocationTrackingOff = parent.getString(R.string.location_tracking_off);
  }

  /**
   * Load all necessary data to start the application.
   */
  public void loadData()
  {
//    trackLoader.loadData();

    // Set location mode.
    mScreen.setStartupViewportMode(Viewport.MODE_LOCATION);
    mState.lockLocation();
  }

  public GpsLocationStatus getGpsLocationStatus()
  {
    return mGpsLocationStatus;
  }

  public void selectLocation()
  {
    mState.setSelectedLocation();
    LayerLocation.resetViewport();
  }

  public void switchLocationState()
  {
    if (mState.isSelectedLocation()) {
      mState.clearLocationSelection();
    }
    else {
      mState.setSelectedLocation();
      LayerLocation.resetViewport();
    }
  }

  public void clearTrackSelection()
  {
    mTrackLoader.clearTrackSelection();
  }

  public void selectOpenTrack()
  {
    mTrackLoader.selectOpenTrack();
  }

  public TrackItem getSelectedTrack()
  {
    return mTrackLoader.getSelectedTrack();
  }

  public ArrayList<Long> getTrackList()
  {
    mTrackLoader.items().sortItems();
    return mTrackLoader.items().getIdList();
  }

  public TrackCollection getTracks()
  {
    return mTrackLoader.items();
  }

  public Screen getScreen()
  {
    return mScreen;
  }

  /**
   * @param width
   * @param height
   * @param screenOrientation
   */
  public void surfaceSizeChanged(int width, int height, int screenOrientation)
  {
    mTrackLoader.items().surfaceSizeChanged(width, height, screenOrientation);
  }

  /**
   * @param event
   */
  public void shiftViewport(float dx, float dy)
  {
    // Shift viewport
    synchronized(mScreen)
    {
      mScreen.shiftViewport(dx, dy);
    }

    // Disable tracking location if map view shifted
    if ((dx > 2) || (dy > 2)) {
//      disableLocationTracking();
    }
  }

  public boolean isLocationInUse()
  {
    return mState.isLocationInUse();
  }

  private void disableLocationTracking()
  {
    if (mState.isLocationInUse()) {
      mState.releaseLocation();
      Log.d("DataLoader", mMsgLocationTrackingOff);
    }
  }

  /**
   *
   */
  public void updateObjectsState()
  {
    mTrackLoader.items().updateObjectsState();

    // Select an open track at startup
    if (bSelectOpenTrackAtStart) {
      bSelectOpenTrackAtStart = false;
      mTrackLoader.selectOpenTrack();
    }
  }

  /**
   * Performs the drawing operation. First, it sets the screen size according
   * to the width and height of the drawing area. And then,
   *
   * @param canvas
   * @param area
   */
  public void doDraw(Canvas canvas, Rect area)
  {
    synchronized(mScreen)
    {
      mScreen.setSize(area.width(), area.height());
    }
    // Draw tracks
    mTrackLoader.items().doDraw(canvas, area, mState.getSelectedTrack());
  }
}
